#ifndef ___REFINEMENT_H_
#define ___REFINEMENT_H_

#include <OGF/cells/common/common.h>
#include <OGF/cells/map/map.h>
#include <OGF/cells/map/map_attributes.h>

#include <OGF/basic/types/counted.h>
#include <OGF/math/attributes/attribute_adapter.h>
#include <OGF/surface/grob/surface.h>

#include <OGF/math/linear_algebra/vector.h>
#include <OGF/math/linear_algebra/matrix.h>
#include <OGF/math/geometry/types.h>

#include <OGF/cells/map/ext_map_editor.h>
#include <OGF/cells/map/geometry.h>
#include <OGF/cells/map/map_cell_heap.h>  
#include <OGF/cells/graph/graph_editor.h>
#include <OGF/cells/graph/graph_attributes.h>
#include <OGF/scene_graph/types/scene_graph.h>
#include <OGF/surface/grob/line.h>

#include <string>
#include <vector>
#include <set>
#include <iostream>
#include <queue>

namespace OGF {

	typedef std::set<Map::Vertex*> VertexSet;

	//Class to refine a skeleton given a surface from which the skeleton was derived
	class Refinement {
	public:
	//Preconditions: 
	//	-skeletonSurface has GraphVertexAttribute with 
	//		type: VertexSet
	//		name: "ASSOCIATED_VERTS"				//mapping from downsampled skeleton nodes to original verts
	//  -oldSurface has MapVertexAttribute with
	//		type: Point3d
	//		name: "ORIGINAL_POSITIONS"			//mapping from original vertices to their contracted positions
	//	where the vertex set at each skeleton vertex contains the edges that collapsed into
	//      being that one vertex.
	//	-skeletonSurface has NO faces
	//Postconditions:
	//	The skeleton vertices get moved to the reweighted position/average of its respective
	//	non-skeleton vertices.
		static void Refine(Surface* oldSurface, Line* skeletonSurface);

	private:
		static void calculateVertexAvgDisplacement(Surface* oldSurface, Line* skeletonSurface, Graph::Vertex* v);
		static void calculateAvgDisplacements(Surface* oldSurface, Line* skeletonSurface);

		static void repositionSkeletonNode(Surface* oldSurface, Line* skeletonSurface, Graph::Vertex* v);
		static void repositionSkeletonNodes(Surface* oldSurface, Line* skeletonSurface);
	};


}  //namespace
#endif // ___SIMPLIFY_H__
